﻿using BaseModule;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BaseApplication
{
    public class HostService : IHostProcessor
    {
        public List<IBaseModule> Modules { get; set; }
        public string Message { get; set; }
        public HostService()
        {
            Modules = new List<IBaseModule>();
        }
        public void FindModules(string path)
        {
            DirectoryInfo folder = new DirectoryInfo(path);
            var dlls = folder.GetFiles("*.dll");
            foreach (var file in dlls)
            {
                LoadModule(file.FullName);
            }
        }

        private void LoadModule(string filePath)
        {
            Assembly pluginAssembly = Assembly.LoadFrom(filePath);
            object[] pluginAttributes;

            foreach (Type pluginType in pluginAssembly.GetTypes())
            {
                pluginAttributes = pluginType.GetCustomAttributes(typeof(ModuleInfoAttribute), true);
                if (pluginType.IsPublic && !pluginType.IsAbstract && null != pluginAttributes)
                {
                    Type interfaceType = pluginType.GetInterface("BaseModule.IBaseModule", true);
                    if (null != interfaceType) // gets the right interface-type.
                    {
                        IBaseModule module = (IBaseModule)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));

                        module.Attributes = pluginAttributes[0] as ModuleInfoAttribute;
                        module.Initialize(this);

                        Modules.Add(module);

                        module = null;
                    }

                    interfaceType = null; // clean up...
                }
            }

            pluginAssembly = null; // clean up...
        }

        public void Report(string message)
        {
            this.Message = message;
        }

        public void Dispose()
        {
            Modules.Clear();
        }

    }
}
